package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.ClearCache;
import com.atguigu.tingshu.common.cache.RedisCache;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.atguigu.tingshu.vo.album.AlbumStatVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author xiongkunYang
 */
@Slf4j
@Service
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    private final AlbumAttributeValueMapper albumAttributeValueMapper;
    private final AlbumStatMapper albumStatMapper;
    private final TrackInfoMapper trackInfoMapper;
    private final RabbitService rabbitService;

    public AlbumInfoServiceImpl(AlbumAttributeValueMapper albumAttributeValueMapper, AlbumStatMapper albumStatMapper, TrackInfoMapper trackInfoMapper, RabbitService rabbitService) {
        this.albumAttributeValueMapper = albumAttributeValueMapper;
        this.albumStatMapper = albumStatMapper;
        this.trackInfoMapper = trackInfoMapper;
        this.rabbitService = rabbitService;
    }


    /**
     * 保存专辑信息
     *
     * @param userId      用户ID，用于关联用户和专辑信息
     * @param albumInfoVo 专辑信息的视图对象，包含要保存的专辑基本信息和专辑属性值列表
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public void saveAlbumInfo(Long userId, AlbumInfoVo albumInfoVo) {
        // 保存专辑信息（album_info）
        AlbumInfo albumInfo = BeanUtil.copyProperties(albumInfoVo, AlbumInfo.class);
        albumInfo.setUserId(userId);
        albumInfo.setTracksForFree(5);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        super.baseMapper.insert(albumInfo);
        Long albumId = albumInfo.getId();

        // 保存专辑标签值（album_attribute_value）
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (CollectionUtil.isNotEmpty(albumAttributeValueVoList)) {
            albumAttributeValueVoList.forEach(albumAttributeValueVo -> {
                AlbumAttributeValue albumAttributeValue = BeanUtil.copyProperties(albumAttributeValueVo, AlbumAttributeValue.class);
                albumAttributeValue.setAlbumId(albumId);
                albumAttributeValueMapper.insert(albumAttributeValue);
            });
        }

        // 保存专辑统计信息（album_stat）统计类型：0401-播放量 0402-订阅量 0403-购买量 0404-评论数
        this.saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_PLAY, 0);
        this.saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_SUBSCRIBE, 0);
        this.saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_BUY, 0);
        this.saveAlbumStat(albumId, SystemConstant.ALBUM_STAT_COMMENT, 0);

        // TODO 调用内容审核接口（第三方阿里云）对专辑内容（封面、文字）

        // 审核通过后发送上架专辑消息到 RabbitMQ
        if ("1".equals(albumInfo.getIsOpen())) {
            this.rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, albumId);
        }
    }


    @Override
    public void saveAlbumStat(Long albumId, String statType, int statNum) {
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatType(statType);
        albumStat.setStatNum(statNum);
        this.albumStatMapper.insert(albumStat);
    }

    @Override
    public IPage<AlbumListVo> getUserAlbumPage(Page<AlbumListVo> pageInfo, AlbumInfoQuery albumInfoQuery) {
        return this.baseMapper.selectUserAlbumPage(pageInfo, albumInfoQuery);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void removeAlbumInfoById(Long id) {
        // 根据专辑ID查询该专辑下的声音，如果存在关联声音则不删除
        Long count = this.trackInfoMapper.selectCount(new LambdaQueryWrapper<TrackInfo>()
                .eq(TrackInfo::getAlbumId, id));
        if (count > 0) {
            log.error("专辑下有声音，请先删除专辑下的声音");
            throw new GuiguException(ResultCodeEnum.ALBUM_HAS_TRACK);
        }

        // 删除专辑信息
        this.baseMapper.deleteById(id);

        // 删除专辑属性值
        this.albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, id));

        // 删除专辑统计信息
        this.albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>()
                .eq(AlbumStat::getAlbumId, id));

        // 同步删除索引库中专辑文档
        this.rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, id);
    }

    @Override
    @RedisCache(prefix = RedisConstant.ALBUM_INFO_PREFIX)
    public AlbumInfo getAlbumInfoById(Long id) {
        AlbumInfo albumInfo = this.baseMapper.selectById(id);
        if (albumInfo != null) {
            List<AlbumAttributeValue> albumAttributeValueList = this.albumAttributeValueMapper.selectList(new LambdaQueryWrapper<AlbumAttributeValue>()
                    .eq(AlbumAttributeValue::getAlbumId, id));
            albumInfo.setAlbumAttributeValueList(albumAttributeValueList);
        }
        return albumInfo;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    @ClearCache(prefix = RedisConstant.ALBUM_INFO_PREFIX,keyField = "id")
    public void updateAlbumInfoById(Long id, AlbumInfoVo albumInfoVo) {
        // 查询数据库的旧专辑信息，用于判断专辑上下架状态是否变更
        AlbumInfo oldAlbumInfo = this.baseMapper.selectById(id);
        // 修改专辑信息
        AlbumInfo albumInfo = BeanUtil.copyProperties(albumInfoVo, AlbumInfo.class);
        albumInfo.setId(id);
        this.baseMapper.updateById(albumInfo);

        // 删除专辑标签值
        this.albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>()
                .eq(AlbumAttributeValue::getAlbumId, id));

        // 保存专辑标签值（album_attribute_value）
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (CollectionUtil.isNotEmpty(albumAttributeValueVoList)) {
            albumAttributeValueVoList.forEach(albumAttributeValueVo -> {
                AlbumAttributeValue albumAttributeValue = BeanUtil.copyProperties(albumAttributeValueVo, AlbumAttributeValue.class);
                albumAttributeValue.setAlbumId(id);
                albumAttributeValueMapper.insert(albumAttributeValue);
            });
        }
        // 如果是开放专辑自动将更新后的专辑信息同步到索引库
        if ("1".equals(albumInfoVo.getIsOpen())) {
            this.rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_UPPER, id);
        } else if ("1".equals(oldAlbumInfo.getIsOpen()) && "0".equals(albumInfoVo.getIsOpen())) {
            this.rabbitService.sendMessage(MqConst.EXCHANGE_ALBUM, MqConst.ROUTING_ALBUM_LOWER, id);
        }
    }

    @Override
    public List<AlbumInfo> getUserAllAlbumList(Long userId) {
        LambdaQueryWrapper<AlbumInfo> queryWrapper = new LambdaQueryWrapper<AlbumInfo>()
                .select(AlbumInfo::getId, AlbumInfo::getAlbumTitle, AlbumInfo::getStatus)
                .eq(AlbumInfo::getUserId, userId)
                .orderByDesc(AlbumInfo::getUpdateTime)
                // 只获取50条记录
                .last(" limit 50 ");
        return this.baseMapper.selectList(queryWrapper);
    }

    @Override
    @RedisCache(prefix = RedisConstant.ALBUM_STAT_PREFIX)
    public AlbumStatVo getAlbumStatVoByAlbumId(Long albumId) {
//        AlbumStatVo albumStatVo = new AlbumStatVo();
//        albumStatVo.setAlbumId(albumId);
//        List<AlbumStat> albumStatList = this.albumStatMapper.selectList(new LambdaQueryWrapper<AlbumStat>()
//                .eq(AlbumStat::getAlbumId, albumId));
//        Map<String, Integer> statMap = albumStatList.stream().collect(Collectors.toMap(AlbumStat::getStatType, AlbumStat::getStatNum));
//        albumStatVo.setPlayStatNum(statMap.get(SystemConstant.ALBUM_STAT_PLAY));
//        albumStatVo.setSubscribeStatNum(statMap.get(SystemConstant.ALBUM_STAT_SUBSCRIBE));
//        albumStatVo.setBuyStatNum(statMap.get(SystemConstant.ALBUM_STAT_BUY));
//        albumStatVo.setCommentStatNum(statMap.get(SystemConstant.ALBUM_STAT_COMMENT));
//        return albumStatVo;
        return this.albumStatMapper.selectAlbumStatVoByAlbumId(albumId);
    }
}
